﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Security.Cryptography;
using System.Text;
using SevenDrops.Helpers;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Diagnostics;

namespace SevenDrops.OAuth
{
    public static class OAuthClient
    {
        public static string GetOAuthHeader(Dictionary<string, string> parameters, string httpMethod, string url,
    string consumerSecret, string tokenSecret)
        {
            parameters = parameters.OrderBy(x => x.Key).ToDictionary(v => v.Key, v => v.Value);

            string concat = string.Empty;

            string OAuthHeader = "OAuth ";
            foreach (string k in parameters.Keys)
            {
                 concat += k + "=" + parameters[k] + "&";
                 OAuthHeader += k + "=" + "\"" + parameters[k] + "\", ";
            }

            concat = concat.Remove(concat.Length - 1, 1);
            concat = StringHelper.EncodeToUpper(concat);

            concat = httpMethod + "&" + StringHelper.EncodeToUpper(url) + "&" + concat;

            byte[] content = Encoding.UTF8.GetBytes(concat);

            HMACSHA1 hmac = new HMACSHA1(Encoding.UTF8.GetBytes(consumerSecret + "&" + tokenSecret));
            hmac.ComputeHash(content);

            string hash = Convert.ToBase64String(hmac.Hash);
            hash = hash.Replace("-", "");

            OAuthHeader += "oauth_signature=\"" + StringHelper.EncodeToUpper(hash) + "\"";

            return OAuthHeader;
        }

        public static void Upload(string name, byte[] content, string token, string apiKey, string consumerSecret, string tokenSecret)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();

            parameters.Add("oauth_consumer_key", apiKey);
            parameters.Add("oauth_signature_method", "HMAC-SHA1");
            parameters.Add("oauth_timestamp", CurrentUNIXTimestamp.Get());
            parameters.Add("oauth_nonce", Guid.NewGuid().ToString().Replace("-", ""));
            parameters.Add("oauth_token", token);
            parameters.Add("oauth_version", "1.0");
            parameters.Add("file", name);

            string OAuthHeader = GetOAuthHeader(parameters, "POST", "https://api-content.dropbox.com/0/files/dropbox/SevenDrops", consumerSecret, tokenSecret);

            string boundary = Guid.NewGuid().ToString();
            string header = "--" + boundary;
            string footer = "--" + boundary + "--";

            HttpWebRequest uploadRequest = (HttpWebRequest)WebRequest.Create("https://api-content.dropbox.com/0/files/dropbox/SevenDrops");
            uploadRequest.ContentType = "multipart/form-data; boundary=" + boundary;
            uploadRequest.Method = "POST";
            uploadRequest.Headers["Authorization"] = OAuthHeader;

            StringBuilder headers = new StringBuilder();
            headers.AppendLine(header);
            headers.AppendLine("Content-Disposition: file; name=\"file\"; filename=\""+ name +"\"");
            headers.AppendLine("Content-Type: application/octet-stream");
            headers.AppendLine();
            headers.AppendLine(Encoding.GetEncoding("iso-8859-1").GetString(content, 0, content.Length));
            headers.AppendLine(footer);

            byte[] contents = Encoding.GetEncoding("iso-8859-1").GetBytes(headers.ToString());

            object[] data = new object[2] { uploadRequest, contents };
            uploadRequest.BeginGetRequestStream(new AsyncCallback(GetData), data);
        }

        static void GetData(IAsyncResult result)
        {
            object[] data = (object[])result.AsyncState;
            byte[] content = (byte[])data[1];

            HttpWebRequest request = (HttpWebRequest)data[0];

            Stream requestStream = request.EndGetRequestStream(result);
            requestStream.Write(content, 0, content.Length);
            requestStream.Close();

            request.BeginGetResponse(new AsyncCallback(GetResponse), request);
            
        }

        static void GetResponse(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);

            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                string responseText = reader.ReadToEnd();
                Debug.WriteLine(responseText);
            }

            App.mainPageDisp.BeginInvoke(new Action(() =>
            {
                App.uploadCounter.Counter--;
            }));
        }
    }
}
